﻿/* $RCSFile: GatewaySubSystem.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/Addonnice.ECommerce.GatewaySubSystem/GatewaySubSystem.cs $
 * $log$
 * Revision 8 2010/08/09 10:07:05  christian.surieux
 *   Added Log comment to all cs files
 */

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Configuration;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml;
using System.Diagnostics;
using System.Globalization;

using AddonNice.Diagnostics;

namespace AddonNice.ECommerce.Gateways
{
    public class GatewaySubSystem : ConfigurationSection
    {
        public static void CreateSection(string GatewayType,string GatewayName,string GatewayClass,string loadAssembly)
        {
            if ( InstallTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]GatewaySubSystem CreateSection GatewayType: {0}, GatewayName: {1}, GatewayClass: {2}, loadAssembly: {3}", 
                    new object[]{GatewayType,GatewayName,GatewayClass,loadAssembly}),InstallTraceSwitch.Sw.Info);
            try
            {

                GatewaySubSystem customSection;

                // Get the current configuration file.
                System.Configuration.Configuration config       =   WebConfigurationManager.OpenWebConfiguration("~");

                // Create the section entry  
                // in <configSections> and the 
                // related target section in <configuration>.
                if ( config.Sections["GatewaySubSystem"] == null )
                {
                    if ( InstallTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( "[V]GatewaySubSystem CreateSectionGateway creating section GatewaySubSystem.",InstallTraceSwitch.Sw.Info);
                    customSection                               =   new GatewaySubSystem();
                    GatewayType tp                              =   new GatewayType(GatewayType);
                    if ( InstallTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]GatewaySubSystem CreateSectionGateway GatewayType added Name: {0}",tp.Name),InstallTraceSwitch.Sw.Info);
                    Gateway gtw                                 =   new Gateway(GatewayName,GatewayClass,loadAssembly);
                    if ( InstallTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]GatewaySubSystem CreateSection Gateway added GatewayName: {0}, GatewayClass: {1}",GatewayName,GatewayClass),InstallTraceSwitch.Sw.Info);
                    tp.Gateways.Add(gtw);
                    customSection.Types.Add(tp);
                    config.Sections.Add("GatewaySubSystem",customSection);
                    if ( InstallTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]GatewaySubSystem CreateSection name: {0} created", customSection.SectionInformation.Name),InstallTraceSwitch.Sw.Info);
                }
                else
                {
                    if ( InstallTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( "[V]GatewaySubSystem CreateSectionGateway section found.",InstallTraceSwitch.Sw.Info);
                    customSection                               =   (GatewaySubSystem)config.Sections["GatewaySubSystem"];
                    if ( InstallTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( "[V]GatewaySubSystem CreateSectionGateway section Company found.",InstallTraceSwitch.Sw.Info);
                    if ( customSection.Types[GatewayType] == null )
                    {
                        GatewayType tp                          =   new GatewayType(GatewayType);
                        if ( InstallTraceSwitch.Sw.TraceVerbose )
                            Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]GatewaySubSystem CreateSectionGateway GatewayType added Name: {0}",tp.Name),InstallTraceSwitch.Sw.Info);
                        Gateway gtw                             =   new Gateway(GatewayName,GatewayClass,loadAssembly);
                        if ( InstallTraceSwitch.Sw.TraceVerbose )
                            Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]GatewaySubSystem CreateSection Gateway added GatewayName: {0}, GatewayClass: {1}",GatewayName,GatewayClass),InstallTraceSwitch.Sw.Info);
                        tp.Gateways.Add(gtw);
                        customSection.Types.Add(tp);
                    }
                    else
                    {
                        GatewayType tp                          =   customSection.Types[GatewayType];
                        if ( InstallTraceSwitch.Sw.TraceVerbose )
                            Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]GatewaySubSystem CreateSection GatewayType found Name: {0}",tp.Name),InstallTraceSwitch.Sw.Info);
                        if ( tp.Gateways[GatewayName] == null )
                        {
                            Gateway gtw                         =   new Gateway(GatewayName,GatewayClass,loadAssembly);
                            if ( InstallTraceSwitch.Sw.TraceVerbose )
                                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]GatewaySubSystem CreateSection Gateway added GatewayName: {0}, GatewayClass: {1}",GatewayName,GatewayClass),InstallTraceSwitch.Sw.Info);
                            tp.Gateways.Add(gtw);
                        }
                        else
                        {
                            Gateway gtw                         =   tp.Gateways[GatewayName];
                            gtw.GatewayClass                    =   GatewayClass;
                            gtw.LoadAssembly                    =   loadAssembly;
                            if ( InstallTraceSwitch.Sw.TraceVerbose )
                                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]GatewaySubSystem CreateSectionGateway Gateway modified GatewayName: {0}, GatewayClass: {1}",GatewayName,GatewayClass),InstallTraceSwitch.Sw.Info);
                        }
                    }
                }
                customSection.SectionInformation.ForceSave      =   true;
                config.Save(ConfigurationSaveMode.Full);

                if ( InstallTraceSwitch.Sw.TraceVerbose )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]GatewaySubSystem CreateSection section saved Name: {0}.", customSection.SectionInformation.Name),InstallTraceSwitch.Sw.Info);
            }
            catch (Exception ex)
            {
                if ( InstallTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]GatewaySubSystem CreateSection ex: {0}", ex),InstallTraceSwitch.Sw.Info);
                throw;
            }
            if ( InstallTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine("[V]GatewaySubSystem CreateSection END",InstallTraceSwitch.Sw.Info);
        }
        
        public static GatewaySubSystem GetConfig()
        {
            return ConfigurationManager.GetSection("GatewaySubSystem") as GatewaySubSystem;
        }

        [ConfigurationProperty("Types")]
        public GatewayTypeCollection Types
        {
            get
            {
                return this["Types"] as GatewayTypeCollection;
            }
        }
    }


    public class GatewayTypeCollection : ConfigurationElementCollection
    {
        public GatewayType this[int index]
        {
            get
            {
                return base.BaseGet(index) as GatewayType;
            }
            set
            {
                if (base.BaseGet(index) != null)
                {
                    base.BaseRemoveAt(index);
                }
                this.BaseAdd(index, value);
            }
        }

       new public GatewayType this[string Name]
        {
            get
            {
                return (GatewayType)BaseGet(Name);
            }
        }

        protected override ConfigurationElement CreateNewElement()
        {
            return new GatewayType();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((GatewayType)element).Name;
        }

        /**/
        public override ConfigurationElementCollectionType CollectionType
        {
            get
            {
                return ConfigurationElementCollectionType.AddRemoveClearMap;
            }
        }

        protected override ConfigurationElement CreateNewElement(string GatewayTypeName)
        {
            return new GatewayType(GatewayTypeName);
        }

        public new string AddElementName
        {
            get
            { return base.AddElementName; }

            set
            { base.AddElementName = value; }

        }

        public new string ClearElementName
        {
            get
            { return base.ClearElementName; }

            set
            { base.AddElementName = value; }

        }

        public new string RemoveElementName
        {
            get
            { return base.RemoveElementName; }
        }

        public new int Count
        {
            get { return base.Count; }
        }

 
        public int IndexOf(GatewayType product)
        {
            return BaseIndexOf(product);
        }

        public void Add(GatewayType product)
        {
            BaseAdd(product);
            // Add custom code here.
        }

        protected override void BaseAdd(ConfigurationElement element)
        {
            BaseAdd(element, false);
            // Add custom code here.
        }

        public void Remove(GatewayType productLic)
        {
            if (BaseIndexOf(productLic) >= 0)
                BaseRemove(productLic.Name);
        }

        public void RemoveAt(int index)
        {
            BaseRemoveAt(index);
        }

        public void Remove(string name)
        {
            BaseRemove(name);
        }

        public void Clear()
        {
            BaseClear();
            // Add custom code here.
        }
    }

    public class GatewayType : ConfigurationElement
    {
        [ConfigurationProperty("Name", IsRequired = true, IsKey=true)]
        public string Name
        {
            get
            {
                return this["Name"] as string;
            }
            set
            {
                this["Name"] = value;
            }
        }

        public GatewayType()
        {}

        public GatewayType(string wName)
        {
            Name     =   wName;
        }

        [ConfigurationProperty("Gateways")]
        public GatewayCollection Gateways
        {
            get
            {
                return this["Gateways"] as GatewayCollection;
            }
        }
    }

    public class GatewayCollection : ConfigurationElementCollection
    {
        public Gateway this[int index]
        {
            get
            {
                return base.BaseGet(index) as Gateway;
            }
            set
            {
                if (base.BaseGet(index) != null)
                {
                    base.BaseRemoveAt(index);
                }
                this.BaseAdd(index, value);
            }
        }

       new public Gateway this[string Name]
        {
            get
            {
                return (Gateway)BaseGet(Name);
            }
        }

        protected override ConfigurationElement CreateNewElement()
        {
            return new Gateway();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((Gateway)element).GatewayName;
        }

        /**/
        public override ConfigurationElementCollectionType CollectionType
        {
            get
            {
                return ConfigurationElementCollectionType.AddRemoveClearMap;
            }
        }

        protected override ConfigurationElement CreateNewElement(string GatewayName)
        {
            return new Gateway(GatewayName);
        }

        public new string AddElementName
        {
            get
            { return base.AddElementName; }

            set
            { base.AddElementName = value; }

        }

        public new string ClearElementName
        {
            get
            { return base.ClearElementName; }

            set
            { base.AddElementName = value; }

        }

        public new string RemoveElementName
        {
            get
            { return base.RemoveElementName; }
        }

        public new int Count
        {
            get { return base.Count; }
        }

 
        public int IndexOf(Gateway product)
        {
            return BaseIndexOf(product);
        }

        public void Add(Gateway product)
        {
            BaseAdd(product);
            // Add custom code here.
        }

        protected override void BaseAdd(ConfigurationElement element)
        {
            BaseAdd(element, false);
            // Add custom code here.
        }

        public void Remove(Gateway productLic)
        {
            if (BaseIndexOf(productLic) >= 0)
                BaseRemove(productLic.GatewayName);
        }

        public void RemoveAt(int index)
        {
            BaseRemoveAt(index);
        }

        public void Remove(string name)
        {
            BaseRemove(name);
        }

        public void Clear()
        {
            BaseClear();
            // Add custom code here.
        }
    }

    public class Gateway : ConfigurationElement
    {

        [ConfigurationProperty("GatewayName", IsRequired = true, IsKey=true)]
        public string GatewayName
        {
            get
            {
                return this["GatewayName"] as string;
            }
            set
            {
                this["GatewayName"] = value;
            }
        }

        [ConfigurationProperty("GatewayClass", IsRequired = true, IsKey=true)]
        public string GatewayClass
        {
            get
            {
                return this["GatewayClass"] as string;
            }
            set
            {
                this["GatewayClass"] = value;
            }
        }

        [ConfigurationProperty("loadAssembly", IsRequired = true)]
        public string LoadAssembly
        {
            get
            {
                return this["loadAssembly"] as string;
            }
            set
            {
                this["loadAssembly"] = value;
            }
        }

        public Gateway()
        {}

        public Gateway(string wGatewayName)
        {
            GatewayName     =   wGatewayName;
        }

        public Gateway(string wGatewayName,string wGatewayClass,string wLoadAssembly)
        {
            GatewayName     =   wGatewayName;
            GatewayClass    =   wGatewayClass;
            LoadAssembly    =   wLoadAssembly;
        }
    }
}
